
<h1>CSS编码规范</h1>
<h2>1 前言</h2>
<p>CSS作为网页样式的描述语言，在百度一直有着广泛的应用。本文档的目标是使CSS代码风格保持一致，容易被理解和被维护。</p>
<p>虽然本文档是针对CSS设计的，但是在使用各种CSS的预编译器(如less、sass、stylus等)时，适用的部分也应尽量遵循本文档的约定。</p>

<h2>2 通用</h2>
<h3>2.1 选择器</h3>
<h4>[强制] 如无必要，不得为 <code>id</code>、<code>class</code> 选择器添加类型选择器进行限定。</h4>
<p>解释：</p>
<p>在性能和维护性上，都有一定的影响。</p>
<p>示例：</p>
<pre>/* good */
#error,
.danger-message {
    font-color: #c00;
}

/* bad */
dialog#error,
p.danger-message {
    font-color: #c00;
}
</pre>
<h3>2.2 !important</h3>
<h4>[建议] 尽量不使用 <code>!important</code> 声明。</h4>
<h4>[建议] 当需要强制指定样式且不允许任何场景覆盖时，通过标签内联和 <code>!important</code> 定义样式。</h4>
<p>解释：</p>
<p>必须注意的是，仅在设计上 <code>确实不允许任何其它场景覆盖样式</code> 时，才使用内联的 <code>!important</code> 样式。通常在第三方环境的应用中使用这种方案。下面的 z-index 章节是其中一个特殊场景的典型样例。</p>
<h3>2.3 z-index</h3>
<h4>[建议] 将 <code>z-index</code> 进行分层，对文档流外绝对定位元素的视觉层级关系进行管理。</h4>
<p>解释：</p>
<p>同层的多个元素，如多个由用户输入触发的 Dialog，在该层级内使用相同的 <code>z-index</code> 或递增 <code>z-index</code>。</p>
<p>建议每层包含100个 <code>z-index</code> 来容纳足够的元素，如果每层元素较多，可以调整这个数值。</p>
<h4>[建议] 在可控环境下，期望显示在最上层的元素，<code>z-index</code> 指定为 <code>999999</code>。</h4>
<p>解释：</p>
<p>可控环境分成两种，一种是自身产品线环境；还有一种是可能会被其他产品线引用，但是不会被外部第三方的产品引用。</p>
<p>不建议取值为 <code>2147483647</code>。以便于自身产品线被其他产品线引用时，当遇到层级覆盖冲突的情况，留出向上调整的空间。</p>
<h4>[建议] 在第三方环境下，期望显示在最上层的元素，通过标签内联和 <code>!important</code>，将 <code>z-index</code> 指定为 <code>2147483647</code>。</h4>
<p>解释：</p>
<p>第三方环境对于开发者来说完全不可控。在第三方环境下的元素，为了保证元素不被其页面其他样式定义覆盖，需要采用此做法。</p>
<h2>3 值与单位</h2>

<h3>3.1 数值</h3>
<h4>[强制] 当数值为 0 - 1 之间的小数时，省略整数部分的 <code>0</code>。</h4>
<p>示例：</p>
<pre>/* good */
panel {
    opacity: .8
}

/* bad */
panel {
    opacity: 0.8
}
</pre>
<h3>3.2 url()</h3>
<h4>[强制] <code>url()</code> 函数中的路径不加引号。</h4>
<p>示例：</p>
<pre>body {
    background: url(bg.png);
}
</pre>
<h4>[建议] <code>url()</code> 函数中的绝对路径可省去协议名。</h4>
<p>示例：</p>
<pre>body {
    background: url(//baidu.com/img/bg.png) no-repeat 0 0;
}
</pre>
<h3>3.3 长度</h3>
<h4>[强制] 长度为 <code>0</code> 时须省略单位。 (也只有长度单位可省)</h4>
<p>示例：</p>
<pre>/* good */
body {
    padding: 0 5px;
}

/* bad */
body {
    padding: 0px 5px;
}
</pre>
<h3>3.4 2D 位置</h3>
<h4>[强制] 必须同时给出水平和垂直方向的位置。</h4>
<p>解释：</p>
<p>2D 位置初始值为 <code>0% 0%</code>，但在只有一个方向的值时，另一个方向的值会被解析为 center。为避免理解上的困扰，应同时给出两个方向的值。<a href="http://www.w3.org/TR/CSS21/colors.html#propdef-background-position">background-position属性值的定义</a></p>
<p>示例：</p>
<pre>/* good */
body {
    background-position: center top; /* 50% 0% */
}

/* bad */
body {
    background-position: top; /* 50% 0% */
}
</pre>
<h2>4 文本编排</h2>
<h3>4.1 字体族</h3>
<h4>[强制] <code>font-family</code> 属性中的字体族名称应使用字体的英文 <code>Family Name</code>，其中如有空格，须放置在引号中。</h4>
<p>解释：</p>
<p>所谓英文 Family Name，为字体文件的一个元数据，常见名称如下：</p>
<p>字体 | 操作系统 | Family Name
    -----|----------|------------
    宋体 (中易宋体) | Windows | SimSun
    黑体 (中易黑体) | Windows | SimHei
    微软雅黑 | Windows | Microsoft YaHei
    微软正黑 | Windows | Microsoft JhengHei
    华文黑体 | Mac/iOS | STHeiti
    冬青黑体 | Mac/iOS | Hiragino Sans GB
    文泉驿正黑 | Linux | WenQuanYi Zen Hei
    文泉驿微米黑 | Linux | WenQuanYi Micro Hei</p>
<p>示例：</p>
<pre>h1 {
    font-family: "Microsoft YaHei";
}
</pre>
<h4>[强制] <code>font-family</code> 按「西文字体在前、中文字体在后」、「效果佳 (质量高/更能满足需求) 的字体在前、效果一般的字体在后」的顺序编写，最后必须指定一个通用字体族( <code>serif</code> / <code>sans-serif</code> )。</h4>
<p>解释：</p>
<p>更详细说明可参考<a href="http://www.zhihu.com/question/19911793/answer/13329819">本文</a>。</p>
<p>示例：</p>
<pre>/* Display according to platform */
.article {
    font-family: Arial, sans-serif;
}

/* Specific for most platforms */
h1 {
    font-family: "Helvetica Neue", Arial, "Hiragino Sans GB", "WenQuanYi Micro Hei", "Microsoft YaHei", sans-serif;
}
</pre>
<h4>[强制] <code>font-family</code> 不区分大小写，但在同一个项目中，同样的 <code>Family Name</code> 大小写必须统一。</h4>
<p>示例：</p>
<pre>/* good */
body {
    font-family: Arial, sans-serif;
}

h1 {
    font-family: Arial, "Microsoft YaHei", sans-serif;
}

/* bad */
body {
    font-family: arial, sans-serif;
}

h1 {
    font-family: Arial, "Microsoft YaHei", sans-serif;
}
</pre>
<h3>4.2 字号</h3>
<h4>[强制] 需要在 Windows 平台显示的中文内容，其字号应不小于 <code>12px</code>。</h4>
<p>解释：</p>
<p>由于 Windows 的字体渲染机制，小于 12px 的文字显示效果极差、难以辨认。</p>
<h3>4.3 字体风格</h3>
<h4>[建议] 需要在 Windows 平台显示的中文内容，不要使用除 <code>normal</code> 外的 <code>font-style</code>。其他平台也应慎用。</h4>
<p>解释：</p>
<p>由于中文字体没有 italic 风格的实现，所有浏览器下都会 fallback 到 obilique 实现 (自动拟合为斜体)，小字号下 (特别是 Windows 下会在小字号下使用点阵字体的情况下) 显示效果差，造成阅读困难。</p>

<h2>5 变换与动画</h2>
<h4>[强制] 使用 <code>transition</code> 时应指定 <code>transition-property</code>。</h4>
<p>示例：</p>
<pre>/* good */
.box {
    transition: color 1s, border-color 1s;
}

/* bad */
.box {
    transition: all 1s;
}
</pre>
<h4>[建议] 尽可能在浏览器能高效实现的属性上添加过渡和动画。</h4>
<p>解释：</p>
<p>见<a href="http://www.html5rocks.com/en/tutorials/speed/high-performance-animations/">本文</a>，在可能的情况下应选择这样四种变换：</p>
<ul>
    <li><code>transform: translate(npx, npx);</code></li>
    <li><code>transform: scale(n);</code></li>
    <li><code>transform: rotate(ndeg);</code></li>
    <li><code>opacity: 0..1;</code></li>
</ul>
<p>典型的，可以使用 translate 来代替 left 作为动画属性。</p>
<p>示例：</p>
<pre>/* good */
.box {
    transition: transform 1s;
}
.box:hover {
    transform: translate(20px); /* move right for 20px */
}

/* bad */
.box {
    left: 0;
    transition: left 1s;
}
.box:hover {
    left: 20px; /* move right for 20px */
}
</pre>
<h2>7 响应式</h2>
<h4>[强制] <code>Media Query</code> 不得单独编排，必须与相关的规则一起定义。</h4>
<p>示例：</p>
<pre>/* Good */
/* header styles */
@media (...) {
    /* header styles */
}

/* main styles */
@media (...) {
    /* main styles */
}

/* footer styles */
@media (...) {
    /* footer styles */
}


/* Bad */
/* header styles */
/* main styles */
/* footer styles */

@media (...) {
    /* header styles */
    /* main styles */
    /* footer styles */
}
</pre>
<h4>[强制] <code>Media Query</code> 如果有多个逗号分隔的条件时，应将每个条件放在单独一行中。</h4>
<p>示例：</p>
<pre>@media
(-webkit-min-device-pixel-ratio: 2), /* Webkit-based browsers */
(min--moz-device-pixel-ratio: 2),    /* Older Firefox browsers (prior to Firefox 16) */
(min-resolution: 2dppx),             /* The standard way */
(min-resolution: 192dpi) {           /* dppx fallback */
    /* Retina-specific stuff here */
}
</pre>
<h4>[建议] 尽可能给出在高分辨率设备 (Retina) 下效果更佳的样式。</h4>
<h2>8 兼容性</h2>
<h3>8.1 属性前缀</h3>
<h4>[强制] 带私有前缀的属性由长到短排列，按冒号位置对齐。</h4>
<p>解释：</p>
<p>标准属性放在最后，按冒号对齐方便阅读，也便于在编辑器内进行多行编辑。</p>
<p>示例：</p>
<pre>.box {
    -webkit-box-sizing: border-box;
       -moz-box-sizing: border-box;
            box-sizing: border-box;
}
</pre>
<h3>8.2 Hack</h3>
<h4>[建议] 需要添加 <code>hack</code> 时应尽可能考虑是否可以采用其他方式解决。</h4>
<p>解释：</p>
<p>如果能通过合理的 HTML 结构或使用其他的 CSS 定义达到理想的样式，则不应该使用 hack 手段解决问题。通常 hack 会导致维护成本的增加。</p>
<h4>[建议] 尽量使用 <code>选择器 hack</code> 处理兼容性，而非 <code>属性 hack</code>。</h4>
<p>解释：</p>
<p>尽量使用符合 CSS 语法的 selector hack，可以避免一些第三方库无法识别 hack 语法的问题。</p>
<p>示例：</p>
<pre>/* IE 7 */
*:first-child + html #header {
    margin-top: 3px;
    padding: 5px;
}

/* IE 6 */
* html #header {
    margin-top: 5px;
    padding: 4px;
}
</pre>
<h4>[建议] 尽量使用简单的 <code>属性 hack</code>。</h4>
<p>示例：</p>
<pre>.box {
    _display: inline; /* fix double margin */
    float: left;
    margin-left: 20px;
}

.container {
    overflow: hidden;
    *zoom: 1; /* triggering hasLayout */
}
</pre>
<h3>8.3 Expression</h3>
<h4>[强制] 禁止使用 <code>Expression</code>。</h4>


